package cn.cdzdjd.service.impl;

import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.json.JSONArray;
import org.json.JSONObject;
import org.jsoup.Connection.Response;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.springframework.retry.annotation.Backoff;
import org.springframework.retry.annotation.Recover;
import org.springframework.retry.annotation.Retryable;
import org.springframework.stereotype.Service;

import cn.cdzdjd.constant.BrowserConstant;
import cn.cdzdjd.exception.ErrorCode;
import cn.cdzdjd.exception.RenException;
import cn.cdzdjd.service.DouyinVideoService;
import cn.cdzdjd.util.JsoupUtil;
import cn.cdzdjd.util.UrlUtil;
import cn.cdzdjd.vo.VideoInfoVO;
import lombok.extern.slf4j.Slf4j;

@Service
@Slf4j
public class DouyinVideoServiceImpl implements DouyinVideoService {

	@Retryable(value = { Exception.class }, maxAttempts = 3, backoff = @Backoff(delay = 2000, multiplier = 1.5))
	@Override
	public VideoInfoVO getVideoInfoFromPage(String locationUrl) {
		// 读取url，得到Document
		try {
			Document document = Jsoup.connect(locationUrl).ignoreContentType(true)
					.userAgent(BrowserConstant.USER_AGENT_MOBILE).header("Accept", BrowserConstant.ACCEPT)
					.referrer(locationUrl).get();
			Element element = document.body();
			Element lastElement = element.lastElementChild();
			String data = lastElement.data();
			int start = StringUtils.ordinalIndexOf(data, "{", 1);
			int end = StringUtils.lastOrdinalIndexOf(data, "}", 1);
			String jsonData = StringUtils.substring(data, start, end + 1);
			JSONObject json = new JSONObject(jsonData);
			JSONObject loaderData = json.getJSONObject("loaderData");
			JSONObject page = loaderData.getJSONObject("note_(id)/page");
			JSONObject videoInfoRes = page.getJSONObject("videoInfoRes");
			JSONArray item_list = videoInfoRes.getJSONArray("item_list");
			JSONObject item = item_list.getJSONObject(0);
			String titleDesc = (String) item.get("desc"); // 标题
			if (item.isNull("images")) {
				JSONObject video = item.getJSONObject("video");
				JSONObject play_addr = video.getJSONObject("play_addr");
				JSONArray video_url_list = play_addr.getJSONArray("url_list"); // 视频
				String video_url = video_url_list.getString(0);// 只获取一个可用视频地址
				JSONObject cover_addr = video.getJSONObject("cover");
				JSONArray cover_url_list = cover_addr.getJSONArray("url_list"); // 封面
				String cover_url = cover_url_list.getString(0); // 只获取一个可用封面地址

				List<String> videoList = new ArrayList<>();
				String v_url = video_url.replace("playwm", "play");
				// 临时解决方案
				String final_url = JsoupUtil.downloadVideoUrl(v_url);
				videoList.add(UrlUtil.setHttps(final_url));
				List<String> coverList = new ArrayList<>();
				coverList.add(UrlUtil.setHttps(cover_url));
				return new VideoInfoVO(videoList, coverList, titleDesc, null);
			} else {
				JSONArray images = item.getJSONArray("images");
				List<String> coverList = new ArrayList<>();
				for (int j = 0; j < images.length(); j++) {
					JSONObject image = images.getJSONObject(j);
					JSONArray image_urls = image.getJSONArray("url_list");
					for (int i = 0; i < image_urls.length(); i++) {
						String image_url = image_urls.getString(i); // 只获取一个可用的图片地址
						if (image_url.contains(".jpeg")) {
							coverList.add(UrlUtil.setHttps(image_url));
						}
					}
				}
				return new VideoInfoVO(null, coverList, titleDesc, null);
			}
		} catch (Exception e) {
			e.printStackTrace();
			throw new RenException(ErrorCode.PARSE_ERROR);
		}
	}

	@Override
	public VideoInfoVO getVideoInfoByApi(String locationUrl) {
		String path = UrlUtil.getPath(locationUrl);
		int len = path.length();
		int end = StringUtils.lastOrdinalIndexOf(path, "/", 1);
		String aweme_id = "";
		// 如果最后一位是 /
		if (end == (len - 1)) {
			int start = StringUtils.lastOrdinalIndexOf(path, "/", 2);
			aweme_id = StringUtils.substring(path, start + 1, end);
		} else {
			aweme_id = StringUtils.substring(path, end + 1);
		}

		String code = "";
		if (path.contains("/video/")) {
			code = "201";
		}
		if (path.contains("/slides/")) {
			code = "200";
		}
		String baseUrl = "https://www.iesdouyin.com/web/api/v2/aweme/slidesinfo/?aweme_ids=[" + aweme_id
				+ "]&request_source=" + code;
		try {
			Response response = Jsoup.connect(baseUrl).ignoreContentType(true)
					.userAgent(BrowserConstant.USER_AGENT_MOBILE).header("Accept", BrowserConstant.ACCEPT)
					.referrer(baseUrl).execute();
			String responseBody = response.body();
			// System.out.println(responseBody);
			JSONObject json = new JSONObject(responseBody);
			if (json.isNull("aweme_details")) {
				throw new RenException(ErrorCode.NOT_EXITS);
			}
			JSONArray aweme_details = json.getJSONArray("aweme_details");
			JSONObject aweme_detail = aweme_details.getJSONObject(0);
			// 获取视频标题
			String desc = aweme_detail.getString("desc");
			if (path.contains("/slides/")) {
				JSONArray images = aweme_detail.getJSONArray("images");
				// 多个视频
				List<String> videoList = new ArrayList<>();
				List<String> imageList = new ArrayList<>();
				for (int i = 0; i < images.length(); i++) {
					JSONObject image = images.getJSONObject(i);
					if (image.has("video")) {
						JSONObject video = image.getJSONObject("video");
						// 获取视频播放地址
						JSONObject play_addr = video.getJSONObject("play_addr");
						JSONArray video_play_url_list = play_addr.getJSONArray("url_list");
						String video_url = video_play_url_list.getString(0);
						videoList.add(UrlUtil.setHttps(video_url));
						// 获取视频蒙版地址
						JSONObject cover = video.getJSONObject("cover");
						JSONArray cover_url_list = cover.getJSONArray("url_list");
						String cover_url = cover_url_list.getString(0);
						imageList.add(UrlUtil.setHttps(cover_url));// 加入到视频蒙版地址列表
					} else {
						String poster = image.getJSONArray("url_list").getString(0);
						imageList.add(poster);
					}
				}
				return new VideoInfoVO(videoList, imageList, desc, null);
			}
			if (path.contains("/video/")) {
				JSONObject video = aweme_detail.getJSONObject("video");

				List<String> imageList = new ArrayList<>();
				String posterUrl = video.getJSONObject("cover").getJSONArray("url_list").getString(0)
						.replaceAll("\u0026", "&");
				imageList.add(UrlUtil.setHttps(posterUrl));
				List<String> videoList = new ArrayList<>();
				JSONArray urlList = video.getJSONObject("play_addr").getJSONArray("url_list");
				for (int i = 0; i < urlList.length(); i++) {
					String videoUrl = urlList.getString(i).replaceAll("\u0026", "&");
					videoList.add(UrlUtil.setHttps(videoUrl));
				}
				return new VideoInfoVO(videoList, imageList, desc, null);
			}
		} catch (Exception e) {
			if (e instanceof RenException) {
				throw new RenException(((RenException) e).getCode());
			}
			e.printStackTrace();
		}
		return null;
	}

	@Recover
	public void recover(Exception e) {
		e.printStackTrace();
		log.error("重试3次后依然失败");
		throw new RenException(ErrorCode.PARSE_ERROR);
	}

}
